package com.dingreading.cloud.soms.controller;

import com.dingreading.cloud.common.base.R;
import com.dingreading.cloud.common.util.*;
import com.dingreading.cloud.soms.dto.AddMemberDto;
import com.dingreading.cloud.soms.dto.CaClassMemberDto;
import com.dingreading.cloud.soms.entity.*;
import com.dingreading.cloud.soms.service.*;
import com.dingreading.cloud.soms.util.ScheduleUtil;
import com.google.common.collect.Lists;
import com.mybatisflex.core.paginate.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/front/caClass")
@Api(tags = "门店-排课社团管理")
public class FrontCaClassController {

    @Resource
    protected CaClassService classService;
    @Resource
    protected CaClassMemberService classMemberService;
    @Resource
    protected MembersService membersService;
    @Resource
    protected CaScheduleService scheduleService;
    @Resource
    protected CaScheduleLessonService scheduleLessonService;
    @Resource
    protected CaCallNamesService callNameService;
    @Resource
    protected StoreProjectsService storeProjectsService;
    @Resource
    protected CaClassroomsService classroomsService;


    @ApiOperation(value = "分页列表")
    @PostMapping(value = "/pageList")
    public R<Object> pageList(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "分页公共类") PageUtil pageUtil,
            @ApiParam(value = "社团名") @RequestParam(value = "keyword", required = false) String keyword,
            @ApiParam(value = "导读uid") @RequestParam(value = "teacherUid", required = false) String teacherUid,
            @ApiParam(value = "活动服务uid") @RequestParam(value = "projectUid", required = false) String projectUid,
            @ApiParam(value = "收费状态 1.收费 0.免费") @RequestParam(value = "freeStatus", required = false) Integer freeStatus,
            @ApiParam(value = "是否禁用 1.启用 0.禁用") @RequestParam(value = "enabled", required = false) Integer enabled
    ) {
        Page<CaClass> page = classService.pageList(pageUtil, storeUid, keyword, freeStatus, enabled, projectUid, teacherUid);
        PageBeanDto data = new PageBeanDto();
        data.setTotal(page.getTotalRow());
        data.setList(page.getRecords());
        return R.ok(data);
    }

    @ApiOperation(value = "根据门店uid获取社团")
    @PostMapping(value = "/getClass", produces = "application/json; charset=UTF-8")
    public R<Object> getClass(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "社团名") @RequestParam(value = "keyword", required = false) String keyword,
            @ApiParam(value = "是否禁用 1.启用 0.禁用") @RequestParam(value = "enabled", required = false) Integer enabled
    ) {
        List<CaClass> list = classService.getByStoreUid(storeUid, keyword, enabled);
        return R.ok(list);
    }

    @ApiOperation(value = "获取社团详情")
    @PostMapping(value = "/getBean", produces = "application/json; charset=UTF-8")
    public R<Object> getBean(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "id") @RequestParam(value = "id") Long id
    ) {
        CaClass data = classService.getClassInfo(storeUid, id);
        return R.ok(data);
    }

    @Transactional(rollbackFor = DescribeException.class)
    @ApiOperation(value = "创建/编辑社团")
    @PostMapping(value = "/newBean", produces = "application/json; charset=UTF-8")
    public R<Object> newBean(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "id") @RequestParam(value = "id", required = false) Long id,
            @ApiParam(value = "社团名") @RequestParam(value = "className") String className,
            @ApiParam(value = "服务uid") @RequestParam(value = "projectUid") String projectUid,
            @ApiParam(value = "服务项目名称") @RequestParam(value = "productName") String productName,
            @ApiParam(value = "服务阶段uid") @RequestParam(value = "stageUid") String stageUid,
            @ApiParam(value = "服务阶段名称") @RequestParam(value = "stageName") String stageName,
            @ApiParam(value = "活动室id") @RequestParam(value = "roomId", required = false) Long roomId,
            @ApiParam(value = "活动室名称") @RequestParam(value = "roomName", required = false) String roomName,
            @ApiParam(value = "主讲导读uid") @RequestParam(value = "teacherUid", required = false) String teacherUid,
            @ApiParam(value = "主讲导读名字") @RequestParam(value = "teacherName", required = false) String teacherName,
            @ApiParam(value = "备注") @RequestParam(value = "remark", required = false) String remark
    ) {
        if (StringUtils.isBlank(className)) return R.fail("请输入社团名称");
        if (StringUtils.isBlank(projectUid)) return R.fail("请选择服务");
        if (StringUtils.isBlank(stageUid)) return R.fail("请选择服务阶段");

        StoreProjects storeProjects = storeProjectsService.getByUid(projectUid);
        if (storeProjects == null)
            return R.fail("未查询打牌服务项目");
        Integer freeStatus = storeProjects.getFreeStatus();

        CaClassrooms classrooms = null;
        if (roomId != null) {
            classrooms = classroomsService.getBean(storeUid, roomId);
            if (classrooms == null)
                return R.fail("未查询到教室");
        }

        CaClass data = null;
        if (null == id || id <= 0) {
            // 创建
            data = new CaClass();
            data.setCorpUid(corpUid);
            data.setStoreUid(storeUid);
            data.setStoreName(storeName);
            data.setProjectUid(projectUid);
            data.setProductName(productName);
            data.setFreeStatus(freeStatus);
            data.setStudentNum(0);
            data.setScheduleNum(0);
            data.setCloseStatus(1);
            data.setUid(KitUtil.getUuid());
            data.setEnabled(1);
            data.setAddStaffUid(staffUid);
            data.setAddStaffName(staffName);

            data.setClassName(className);
            if (roomId != null) {
                data.setRoomId(roomId);
                data.setRoomUid(classrooms.getUid());
                data.setRoomName(roomName);
            }
            data.setTeacherUid(teacherUid);
            data.setTeacherName(teacherName);
            data.setStageUid(stageUid);
            data.setStageName(stageName);
            data.setRemark(NepUtil.nullToZero(remark));
            data.setLastStaffUid(staffUid);
            data.setLastStaffName(staffName);
            classService.saveOrUpdate(data);
        } else {
            // 编辑
            data = classService.getById(id);
            if (null == data)
                return R.fail("社团获取失败");
            if (!data.getCloseStatus().equals(1))
                return R.fail("社团已结业");

            boolean b = classService.updateInfo(
                    id, className, roomId, roomName, teacherUid, teacherName, stageUid, stageName, remark,
                    staffUid, staffName
            );
            if (!b)
                return R.fail("操作失败");
            // 更新未进行活动的服务阶段
//            if (b && !data.getStageUid().equals(stageUid)) {
//                scheduleLessonService.updateStage(id, stageUid, stageName);
//            }
        }
        return R.ok();
    }

    @ApiOperation(value = "删除社团")
    @PostMapping(value = "/dropBean", produces = "application/json; charset=UTF-8")
    public R<Object> dropBean(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "社团id") @RequestParam(value = "id") Long id
    ) {
        CaClass data = classService.getClassInfo(storeUid, id);
        if (null == data) return R.fail("社团获取失败");

        // 删除前先判断，有没有排课逻辑
        boolean b = scheduleLessonService.haveClassId(storeUid, id, null);
        if (b) return R.fail("社团已安排活动，不能删除");

        long l = classService.dropBean(storeUid, id);
        if (l <= 0) return R.failDel();
        return R.ok();
    }

    @ApiOperation(value = "更新社团的启用状态")
    @PostMapping(value = "/updateEnabled", produces = "application/json; charset=UTF-8")
    public R<Object> updateEnabled(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "id") @RequestParam(value = "id") Long id,
            @ApiParam(value = "是否禁用 1.启用 0.禁用") @RequestParam(value = "enabled") Integer enabled
    ) {
        // 删除前先判断有没有排课逻辑
        if (enabled.equals(0)) {
            boolean b = scheduleLessonService.haveClassId(storeUid, id, Lists.newArrayList(0, 1));
            if (b) return R.fail("发现未开始/已开始的活动，不能禁用");
        }

        Date time = DateUtil.getNowDatetime();
        long l = classService.updateEnabled(storeUid, id, enabled, staffUid, staffName, time);
        if (l <= 0) return R.fail("更新状态失败");
        return R.ok();
    }

    @ApiOperation(value = "设置社团状态为已结业")
    @PostMapping(value = "/setClose", produces = "application/json; charset=UTF-8")
    public R<Object> setClose(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "id") @RequestParam(value = "id") Long id
    ) {
        // 结业前先判断有没有排课逻辑
        boolean b = scheduleLessonService.haveClassId(storeUid, id, Lists.newArrayList(0, 1));
        if (b) return R.fail("发现未开始/已开始的活动，不能结业");

        Date time = DateUtil.getNowDatetime();
        long l = classService.setClose(storeUid, id, staffUid, staffName, time);
        if (l <= 0) return R.fail("设置结业失败");
        return R.ok();
    }

    @ApiOperation(value = "获取可加入社团的会员列表")
    @PostMapping(value = "/getAddMembers", produces = "application/json; charset=UTF-8")
    public R<Object> getAddMembers(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "分页公共类") PageUtil pageUtil,
            @ApiParam(value = "社团id") @RequestParam(value = "classId") Long classId,
            @ApiParam(value = "会员姓名") @RequestParam(value = "fullName", required = false) String fullName,
            @ApiParam(value = "年级") @RequestParam(value = "grade", required = false) Integer grade,
            @ApiParam(value = "导读员工uid") @RequestParam(value = "readStaffUid", required = false) String readStaffUid
    ) {
        CaClass data = classService.getById(classId);
        // 判断社团是否符合操作要求
        R<Object> r = judgeClass(data);
        if (R.isError(r))
            return r;

        PageDto<AddMemberDto> page = new PageDto<>();
        if (data.getFreeStatus() != null && data.getFreeStatus().equals(0)) {
            // 免费社团，查试听会员
            page = membersService.getByServiceMembers(pageUtil, corpUid, storeUid, fullName, grade, readStaffUid);
        } else {
            // 收费社团，查服务项目的会员
            page = membersService.serviceMemberList(pageUtil, corpUid, storeUid, fullName, grade, data.getProjectUid(), readStaffUid);
        }
        if (page != null) {
            List<AddMemberDto> members = page.getList();
            if (CollectionUtils.isNotEmpty(members)) {
                List<String> addMemberUids = classMemberService.getClassMemberUid(storeUid, classId);
                for (AddMemberDto member : members) {
                    String memberUid = member.getMemberUid();
                    if (CollectionUtils.isEmpty(addMemberUids)) {
                        member.setAddStatus(0);
                    } else {
                        if (addMemberUids.contains(memberUid)) {
                            // 已加入
                            member.setAddStatus(1);
                        } else {
                            // 未加入
                            member.setAddStatus(0);
                        }
                    }
                }
            }
        }
        return R.ok(page);
    }

    @ApiOperation(value = "社团添加会员")
    @PostMapping(value = "/addMember", produces = "application/json; charset=UTF-8")
    public R<Object> addMember(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "社团id") @RequestParam(value = "classId") Long classId,
            @ApiParam(value = "会员uid集合") @RequestParam(value = "memberUids") List<String> memberUids
    ) {
        if (CollectionUtils.isEmpty(memberUids))
            return R.fail("请先选择会员");

        CaClass data = classService.getClassInfo(storeUid, classId);
        // 判断社团是否符合操作要求
        R<Object> r = judgeClass(data);
        if (R.isError(r))
            return r;

        for (String memberUid : memberUids) {
            boolean b = classMemberService.haveMember(storeUid, classId, memberUid);
            if (b)
                return R.fail("会员已加入社团，不能重复操作");
        }

        List<CaClassMember> newList = new ArrayList<>();
        for (String memberUid : memberUids) {
            CaClassMember member = new CaClassMember();
            member.setCorpUid(data.getCorpUid());
            member.setStoreUid(data.getStoreUid());
            member.setStoreName(data.getStoreName());
            member.setClassId(classId);
            member.setClassUid(data.getUid());
            member.setMemberUid(memberUid);
            member.setEnabled(1);
            member.setAddStaffUid(staffUid);
            member.setAddStaffName(staffName);
            member.setLastStaffUid(staffUid);
            member.setLastStaffName(staffName);
            newList.add(member);
        }
        classMemberService.saveOrUpdateBatch(newList);

        // 更新社团会员数量
        long studentNum = classMemberService.getClassMemberNum(storeUid, classId);
        int num = Math.toIntExact(studentNum);
        long l = classService.updateStudentNum(storeUid, classId, staffUid, staffName, num);
        if (l <= 0) return R.fail("修改社团的会员数量失败");

        // 更新活动表关联社团的会员数量
        scheduleService.updateStudentNum(storeUid, classId, num);
        // 更新社团关联的活动的会员数量
        scheduleLessonService.updateStudentNum(storeUid, classId, num);
        // 给当天已进行的活动，添加一条会员点名记录
        String ymd = DateUtil.getCurrentDate();
        List<CaScheduleLesson> lessons = scheduleLessonService.getTodayUseNotOk(ymd, classId);
        if (CollectionUtils.isNotEmpty(lessons)) {
            Map<String, Members> membersMap = new HashMap<>();
            List<Members> members = membersService.getByUids(memberUids);
            if (CollectionUtils.isNotEmpty(members)) {
                membersMap = members.stream().collect(Collectors.toMap(Members::getUid, Function.identity()));
            }
            List<CaCallNames> newCallNames = new ArrayList<>();
            for (CaScheduleLesson lesson : lessons) {
                for (String memberUid : memberUids) {
                    Members memberInfo = membersMap.get(memberUid);
                    CaCallNames callName = ScheduleUtil.newCallName(
                            null, lesson, corpUid, storeUid, storeName, staffUid, staffName,
                            null, memberInfo.getId(), memberUid, memberInfo.getMemberName(), memberInfo.getMob(),
                            1, null, null, 0, null, ""
                    );
                    newCallNames.add(callName);
                }
            }
            callNameService.saveOrUpdateBatch(newCallNames);
        }

        return R.ok();
    }

    @ApiOperation(value = "删除社团里的会员")
    @PostMapping(value = "/dropMember", produces = "application/json; charset=UTF-8")
    public R<Object> dropMember(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "社团id") @RequestParam(value = "classId") Long classId,
            @ApiParam(value = "会员uid") @RequestParam(value = "memberUid") String memberUid
    ) {
        CaClass data = classService.getClassInfo(storeUid, classId);
        if (null == data) return R.fail("社团获取失败");
        if (!data.getEnabled().equals(1)) return R.fail("社团已禁用，不能删除");
        if (!data.getCloseStatus().equals(1)) return R.fail("社团已结业，不能删除");

        long l = classMemberService.dropMember(storeUid, classId, memberUid);
        if (l <= 0) return R.fail("删除会员失败");
        // 更新社团会员数量
        long num = classMemberService.getClassMemberNum(storeUid, classId);
        int studentNum = Math.toIntExact(num);
        l = classService.updateStudentNum(storeUid, classId, staffUid, staffName, studentNum);
        if (l <= 0) return R.fail("更新社团的会员数量失败");

        // 更新活动表关联社团的会员数量
        scheduleService.updateStudentNum(storeUid, classId, studentNum);
        // 更新社团关联的活动的会员数量
        scheduleLessonService.updateStudentNum(storeUid, classId, studentNum);
        // 删除活动内未活动或已活动的社团会员的点名记录
        callNameService.dropClassCallName(storeUid, classId, memberUid);
        return R.ok();
    }

    @ApiOperation(value = "获取社团里的会员列表")
    @PostMapping(value = "/getClassMemberList", produces = "application/json; charset=UTF-8")
    public R<Object> getClassMemberList(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "社团id") @RequestParam(value = "classId") Long classId,
            @ApiParam(value = "姓名或手机号") @RequestParam(value = "keyword", required = false) String keyword
    ) {
        CaClass data = classService.getClassInfo(storeUid, classId);
        if (null == data)
            return R.fail("社团获取失败");

        List<CaClassMemberDto> list = classMemberService.getClassMemberList(corpUid, storeUid, classId, data.getProjectUid(), keyword);
        return R.ok(list);
    }

    /**
     * 判断社团是否符合操作要求
     */
    private R<Object> judgeClass(CaClass data) {
        if (null == data) return R.fail("社团获取失败");
        if (!data.getEnabled().equals(1)) return R.fail("社团已禁用");
        if (!data.getCloseStatus().equals(1)) return R.fail("社团已结业");
        if (null == data.getProjectUid()) return R.fail("社团没有设置服务");
        return R.ok();
    }
}